package cn.gxufe.reliable.message.admin.service.impl;

import cn.gxufe.reliable.message.admin.domain.RMessage;
import cn.gxufe.reliable.message.admin.mapper.MessageMapper;
import cn.gxufe.reliable.message.admin.service.ReliableMessageService;
import cn.gxufe.reliable.message.admin.utils.BeanCopierUtils;
import cn.gxufe.reliable.message.admin.utils.PublishUtils;
import cn.gxufe.reliable.message.common.Message;
import cn.gxufe.reliable.message.common.ResultVo;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

/**
 * @author yingjie.rong
 **/
@Service
public class ReliableMessageServiceImpl extends ServiceImpl<MessageMapper, RMessage> implements ReliableMessageService {

    @Override
    public ResultVo prepare(Message message, String sourceService) {
        RMessage reliableMessage = new RMessage();
        BeanCopierUtils.clone(message,reliableMessage);
        reliableMessage.setStatus(Message.STATUS_PREPARE);
        reliableMessage.setSourceService(sourceService);
        this.baseMapper.insert(reliableMessage);
        PublishUtils.publish(reliableMessage);
        return ResultVo.ok(String.valueOf(reliableMessage.getId()));
    }

    @Override
    public ResultVo finish(Message message,String sourceService) {
        RMessage reliableMessage = this.baseMapper.selectById(message.getId());
        if( message == null ) {
            return ResultVo.error(Message.RESPONSE_CODE_NOT_FOUNT,"not found id : " + message.getId()+", key = "+ message.getKey());
        }
        if( Message.STATUS_FINISH == reliableMessage.getStatus() || RMessage.STATUS_TRY_FINISH == reliableMessage.getStatus()){
            return ResultVo.ok("now status is FINISH !, do nothing ! ");
        }
        int row = baseMapper.updateFinishOrCancel(RMessage.STATUS_TRY_FINISH, reliableMessage.getStatus(), message.getData(), sourceService,message.getId());
        if(row == 1){
            reliableMessage.setStatus( RMessage.STATUS_TRY_FINISH );
            reliableMessage.setTargetService(sourceService);
            PublishUtils.publish(reliableMessage);
        }
        return ResultVo.ok(reliableMessage.getId().toString());
    }

    @Override
    public ResultVo cancel(Message message, String sourceService) {
        RMessage reliableMessage = this.baseMapper.selectById(message.getId());
        if(reliableMessage == null){
            return ResultVo.error(Message.RESPONSE_CODE_NOT_FOUNT,"not found id : " + message.getId()+", key = "+ message.getKey());
        }
        if( Message.STATUS_CANCEL == reliableMessage.getStatus() || RMessage.STATUS_TRY_FINISH == reliableMessage.getStatus() ){
            return ResultVo.ok("now status  is CANCEL !, do nothing ! ");
        }
        int row = baseMapper.updateFinishOrCancel(RMessage.STATUS_TRY_FINISH, reliableMessage.getStatus(), message.getData(), sourceService, message.getId());
        if( row  == 1 ){
            reliableMessage.setStatus( RMessage.STATUS_TRY_FINISH );
            reliableMessage.setTargetService(sourceService);
            PublishUtils.publish(reliableMessage);
        }
        return ResultVo.ok(reliableMessage.getId().toString());
    }

}
